"""配置管理器
统一管理爬虫配置，支持动态加载和更新
"""
import os
import yaml
import json
from typing import Dict, Any, Optional, List
from pathlib import Path
import logging

logger = logging.getLogger(__name__)


class ConfigManager:
    """配置管理器单例类"""
    
    _instance = None
    _config = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        """初始化配置管理器"""
        if self._config is None:
            self.config_dir = Path(__file__).parent.parent.parent / 'config'
            self.config_file = self.config_dir / 'spider_config.yaml'
            self.load_config()
    
    def load_config(self, config_file: Optional[str] = None) -> Dict[str, Any]:
        """加载配置文件
        
        Args:
            config_file: 配置文件路径，默认使用默认配置文件
            
        Returns:
            配置字典
        """
        if config_file:
            self.config_file = Path(config_file)
        
        try:
            if self.config_file.exists():
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    self._config = yaml.safe_load(f)
                logger.info(f"配置文件加载成功: {self.config_file}")
            else:
                logger.warning(f"配置文件不存在: {self.config_file}，使用默认配置")
                self._config = self._get_default_config()
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}，使用默认配置")
            self._config = self._get_default_config()
        
        return self._config
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置
        
        Returns:
            默认配置字典
        """
        return {
            'global': {
                'retry_times': 3,
                'retry_delay': 2,
                'timeout': 30,
                'max_concurrent_requests': 5,
                'rate_limit_per_minute': 30,
                'default_headers': {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
                }
            },
            'platforms': {}
        }
    
    def get_global_config(self) -> Dict[str, Any]:
        """获取全局配置
        
        Returns:
            全局配置字典
        """
        if not self._config:
            self.load_config()
        return self._config.get('global', {})
    
    def get_platform_config(self, platform: str) -> Dict[str, Any]:
        """获取指定平台的配置
        
        Args:
            platform: 平台名称
            
        Returns:
            平台配置字典
        """
        if not self._config:
            self.load_config()
        
        platforms = self._config.get('platforms', {})
        platform_config = platforms.get(platform, {})
        
        # 合并全局配置
        global_config = self.get_global_config()
        merged_config = {**global_config, **platform_config}
        
        return merged_config
    
    def get_enabled_platforms(self) -> List[str]:
        """获取所有启用的平台
        
        Returns:
            启用的平台列表
        """
        if not self._config:
            self.load_config()
        
        platforms = self._config.get('platforms', {})
        enabled = []
        
        for platform, config in platforms.items():
            if config.get('enabled', False):
                enabled.append(platform)
        
        # 按优先级排序
        enabled.sort(key=lambda x: platforms[x].get('priority', 999))
        
        return enabled
    
    def get_field_mapping(self) -> Dict[str, str]:
        """获取字段映射配置
        
        Returns:
            字段映射字典
        """
        if not self._config:
            self.load_config()
        
        return self._config.get('field_mapping', {})
    
    def update_platform_config(self, platform: str, config: Dict[str, Any]) -> bool:
        """更新平台配置
        
        Args:
            platform: 平台名称
            config: 新的配置
            
        Returns:
            是否更新成功
        """
        try:
            if not self._config:
                self.load_config()
            
            if 'platforms' not in self._config:
                self._config['platforms'] = {}
            
            self._config['platforms'][platform] = config
            
            # 保存到文件
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(self._config, f, allow_unicode=True, default_flow_style=False)
            
            logger.info(f"平台配置已更新: {platform}")
            return True
        except Exception as e:
            logger.error(f"更新平台配置失败: {e}")
            return False
    
    def reload(self) -> Dict[str, Any]:
        """重新加载配置文件
        
        Returns:
            新的配置字典
        """
        self._config = None
        return self.load_config()
    
    def get_api_url(self, platform: str, api_name: str, **kwargs) -> Optional[str]:
        """获取API URL，支持参数替换
        
        Args:
            platform: 平台名称
            api_name: API名称
            **kwargs: URL参数
            
        Returns:
            格式化后的URL
        """
        platform_config = self.get_platform_config(platform)
        api_config = platform_config.get('api', {})
        
        if api_name not in api_config:
            logger.warning(f"API {api_name} not found for platform {platform}")
            return None
        
        url = api_config[api_name]
        
        # 替换URL中的参数
        try:
            url = url.format(**kwargs)
        except KeyError as e:
            logger.error(f"URL参数缺失: {e}")
            return None
        
        return url
    
    def get_headers(self, platform: str) -> Dict[str, str]:
        """获取请求头配置
        
        Args:
            platform: 平台名称
            
        Returns:
            请求头字典
        """
        platform_config = self.get_platform_config(platform)
        
        # 获取默认请求头
        headers = platform_config.get('default_headers', {}).copy()
        
        # 添加平台特定的请求头
        platform_headers = platform_config.get('headers', {})
        headers.update(platform_headers)
        
        return headers
    
    def get_rate_limit(self, platform: str) -> int:
        """获取速率限制
        
        Args:
            platform: 平台名称
            
        Returns:
            每分钟最大请求数
        """
        platform_config = self.get_platform_config(platform)
        return platform_config.get('rate_limit_per_minute', 30)
    
    def requires_cookie(self, platform: str) -> bool:
        """检查平台是否需要Cookie
        
        Args:
            platform: 平台名称
            
        Returns:
            是否需要Cookie
        """
        platform_config = self.get_platform_config(platform)
        return platform_config.get('requires_cookie', False)
    
    def requires_auth(self, platform: str) -> bool:
        """检查平台是否需要认证
        
        Args:
            platform: 平台名称
            
        Returns:
            是否需要认证
        """
        platform_config = self.get_platform_config(platform)
        return platform_config.get('requires_auth', False)
    
    def requires_signature(self, platform: str) -> bool:
        """检查平台是否需要签名
        
        Args:
            platform: 平台名称
            
        Returns:
            是否需要签名
        """
        platform_config = self.get_platform_config(platform)
        return platform_config.get('requires_signature', False)


# 创建全局配置管理器实例
config_manager = ConfigManager()